home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 17 / CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso / CUCD / Programming / DiceSource / src / dutil / save / du.c < prev    next >
C/C++ Source or Header  |  1994-02-21  |  4KB  |  209 lines

  1.  
  2. /*
  3.  *  DU <files/dirs>
  4.  *
  5.  * (c)Copyright 1992 Obvious Implementations Corp, All Rights Reserved
  6.  */
  7.  
  8. #include <exec/types.h>
  9. #include <dos/dos.h>
  10. #include <dos/dosextens.h>
  11. #include <clib/dos_protos.h>
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include <setjmp.h>
  16. #include <lib/version.h>
  17.  
  18. #define push_jmp(jbuf,jptr) ((jptr = JmpBase), (JmpBase = jbuf), setjmp(jbuf))
  19. #define forget_jmp(jptr)    { JmpBase = jptr; }
  20.  
  21. typedef struct FileInfoBlock    Fib;
  22. typedef struct InfoData     InfoData;
  23.  
  24. typedef struct Accum {
  25.     struct Accum *Parent;
  26.     char    *Name;
  27.     long    Files;
  28.     long    Dirs;
  29.     long    Blocks;
  30. } Accum;
  31.  
  32. char *AccToName(Accum *);
  33. long GetBlockSize(char *);
  34.  
  35. int mybrk(void);
  36. void ScanDir(Accum *, char *, int);
  37.  
  38. #ifdef _DCC
  39. IDENT("du",".3");
  40. DCOPYRIGHT;
  41. #endif
  42.  
  43. long BlockSize;
  44. jmp_buf *JmpBase;
  45.  
  46. main(ac, av)
  47. short ac;
  48. char *av[];
  49. {
  50.     static Accum ac0;
  51.     short i;
  52.     long bytes;
  53.     jmp_buf jbuf;
  54.     jmp_buf *jptr;
  55.  
  56.     onbreak(mybrk);
  57. //    if (push_jmp(jbuf,jptr)) {
  58.     jptr = JmpBase;
  59.     JmpBase = &jbuf;
  60.     if(setjmp(jbuf)) {
  61.     puts("^C");
  62.     exit(1);
  63.     }
  64.  
  65.     if (ac == 1)
  66.     av[ac++] = "";      /*  overwrites the NULL, which is OK    */
  67.  
  68.     bytes = 0;
  69.     for (i = 1; i < ac; ++i) {
  70.     long lastBlocks = ac0.Blocks;
  71.     BlockSize = GetBlockSize(av[i]);
  72.     ScanDir(&ac0, av[i], 0);
  73.     bytes += (ac0.Blocks - lastBlocks) * BlockSize;
  74.     }
  75.     if (ac > 2)
  76.     printf("%-30s %6ld Kb %6ld BLKS\n", "--TOTAL--", bytes / 1024, ac0.Blocks);
  77.     return(0);
  78. }
  79.  
  80. void
  81. ScanDir(acp, name, level)
  82. Accum *acp;
  83. char *name;
  84. int level;
  85. {
  86.     BPTR lock;
  87.     jmp_buf jbuf;
  88.     jmp_buf *jptr;
  89.  
  90.     if (lock = Lock(name, SHARED_LOCK)) {
  91.     __aligned Fib fib;
  92.     Accum acx;
  93.  
  94. //    if (push_jmp(jbuf,jptr)) {
  95.     jptr = JmpBase;
  96.         JmpBase = jbuf;
  97.         if(setjmp(jbuf)) {
  98.         UnLock(lock);
  99. //        forget_jmp(jptr);
  100.         JmpBase = jptr;
  101.         longjmp(*jptr, 1);
  102.     }
  103.     clrmem(&acx, sizeof(acx));
  104.     acx.Parent = acp;
  105.     acx.Name = name;
  106.  
  107.     memset((char *)&fib,0,sizeof(fib));
  108.     if (Examine(lock, (struct FileInfoBlock *)&fib)) {
  109.         if (fib.fib_DirEntryType > 0) {    /*  dir       */
  110.         long old = CurrentDir(lock);
  111.  
  112. //        forget_jmp(jptr);
  113.         JmpBase = jptr;
  114.  
  115. //        if (push_jmp(jbuf,jptr)) {
  116.         jptr = JmpBase;
  117.             JmpBase = jbuf;
  118.             if(setjmp(jbuf)) {
  119.             CurrentDir(old);
  120.             UnLock(lock);
  121. //            forget_jmp(jptr);
  122.             JmpBase = jptr;
  123.             longjmp(*jptr, 1);
  124.         }
  125.  
  126.         ++acx.Blocks;
  127.         ++acx.Dirs;
  128.         while (ExNext(lock, (struct FileInfoBlock *)&fib)) {
  129.             if((fib.fib_DirEntryType != ST_LINKDIR)
  130.               && (fib.fib_DirEntryType != ST_LINKFILE)
  131.               && (fib.fib_DirEntryType != ST_SOFTLINK)) {
  132.             ScanDir(&acx, fib.fib_FileName, level + 1);
  133.               }
  134.               else {
  135.             ++acx.Files;    // show link as a file
  136.             ++acx.Blocks;
  137.               }
  138.         }
  139.         CurrentDir(old);
  140.         Examine(lock, (struct FileInfoBlock *)&fib);
  141.         } else {                /*  link    */
  142.         ++acx.Files;
  143.         acx.Blocks += 1 + fib.fib_NumBlocks + fib.fib_NumBlocks / 72;
  144.         }
  145.     }
  146. //    forget_jmp(jptr);
  147.     JmpBase = jptr;
  148.     UnLock(lock);
  149.     acp->Blocks += acx.Blocks;
  150.     acp->Dirs   += acx.Dirs;
  151.     acp->Files  += acx.Files;
  152.     if (fib.fib_DirEntryType > 0 && level < 2) {
  153.         printf("%*.*s%-*s %6ld Kb %6ld BLKS\n",
  154.         level, level, "",
  155.         30 /* - level */, AccToName(&acx),
  156.         acx.Blocks / 2, acx.Blocks
  157.         );
  158.     }
  159.     }
  160. }
  161.  
  162. char *
  163. AccToName(acp)
  164. Accum *acp;
  165. {
  166.     static char Buf[1024];
  167.     char *ptr = Buf + sizeof(Buf);
  168.  
  169.     *--ptr = 0;
  170.     while (acp && acp->Name) {
  171.     int len = strlen(acp->Name);
  172.     char c = acp->Name[len-1];
  173.  
  174.     if (*ptr && c && c != '/' && c != ':')
  175.         *--ptr = '/';
  176.     ptr -= len;
  177.     strncpy(ptr, acp->Name, len);
  178.     acp = acp->Parent;
  179.     }
  180.     return(ptr);
  181. }
  182.  
  183. int mybrk()
  184. {
  185.     longjmp(*JmpBase, 1);
  186. }
  187.  
  188. long
  189. GetBlockSize(dir)
  190. char *dir;
  191. {
  192.     long lock;
  193.     long lock2;
  194.     long r = 0;
  195.     InfoData id;
  196.  
  197.     if (lock = Lock(dir, SHARED_LOCK)) {
  198.     while (lock2 = ParentDir(lock)) {
  199.         UnLock(lock);
  200.         lock = lock2;
  201.     }
  202.     if (Info(lock, &id))
  203.         r = id.id_BytesPerBlock;
  204.     UnLock(lock);
  205.     }
  206.     return(r);
  207. }
  208.  
  209.